package com.rois.librois.libRoISComponentServer;

import java.io.File;
import java.util.logging.Logger;

import com.rois.librois.RoIS.Argument;
import com.rois.librois.RoIS.ComponentProfile;
import com.rois.librois.RoIS.ComponentProfileHolder;
import com.rois.librois.RoIS.MessageProfile;
import com.rois.librois.RoIS.Parameter;
import com.rois.librois.RoIS.ParameterListHolder;
import com.rois.librois.RoIS.ResultListHolder;
import com.rois.librois.RoIS.ReturnCode_t;
import com.rois.librois.libRoISComp.ComponentEntity;
import com.rois.librois.libRoISComp.libRoISComp;
import com.rois.librois.libRoISProfileManager.Profiles;

/**
 * Implementation of HRI Component function.
 *
 * @author Miki Sato <miki.sato.1225@gmail.com>
 *
 *    The MIT licence
 *
 *    Copyright (C) 2011
 *      ATR Intelligent Robotics and Communication Laboratories, Japan
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a copy
 *    of this software and associated documentation files (the "Software"), to deal
 *    in the Software without restriction, including without limitation the rights
 *    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 *    of the Software, and to permit persons to whom the Software is furnished to do so,
 *    subject to the following conditions:
 *
 *    The above copyright notice and this permission notice shall be included in all
 *    copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 *    INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 *    PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


public class ComponentInterfaceImpl implements com.rois.librois.libRoISComponentServer.ComponentInterface
{
	private libRoISComp m_lib;
	public ComponentInterfaceImpl(
		libRoISComp  lib_obj
	)
	{
		m_lib = lib_obj;
	}
	private ComponentEntity m_comp;
	public void setComponentEntity(ComponentEntity comp_val)
	{
		m_comp = comp_val;
	}

	@Override
	public ReturnCode_t get_profile(
		String condition,
		ComponentProfileHolder profile
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_ERROR;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [get_profile]\n"
			+">>>condition:"+ condition
		);

		//@@@@@@@@@@@@@@@@@@@@@@@@@
		//@@ NEED CONDITION CHECK
		//@@@@@@@@@@@@@@@@@@@@@@@@@

		// read profile
		Profiles prf_mgr = new Profiles();
		// path
		File path = new File(".");
		String strTemp = path.getAbsoluteFile().getParent()+File.separator;
		strTemp = strTemp + "profile/";
		prf_mgr.setCurrentDirectory(strTemp);
		String strProfileFile = m_lib.getComponentProfileName();
		// component ref
		String strCompRef = prf_mgr.getComponentRef(strProfileFile);
		// component name
		String strCompName = prf_mgr.getComponentName(strProfileFile);
		// load
		prf_mgr.loadComponentProfile(strProfileFile, strCompRef);
		prf_mgr.loadComponentParameterProfile(strProfileFile, strCompRef);
		// output
		ComponentProfile _profile = new ComponentProfile();
		_profile.servername = m_lib.getComponentServerName();
		_profile.name = strCompName;
		_profile.reference_id = strCompRef;
		int index = prf_mgr.m_Components.getIndexByReferenceid(strCompRef);
		int msg_size = 0;
		int prm_size = 0;
		if(index!=-1)
		{
			// command message
			msg_size = prf_mgr.m_Components.command_message.get(index).size;
			_profile.command_message = new MessageProfile[msg_size];
			for(int i=0; i<msg_size; i++)
			{
				prm_size = prf_mgr.m_Components.command_message.get(index).parameters.get(i).size;
				Parameter[] temp_prm = new Parameter[prm_size];
				for(int j=0; j<prm_size; j++)
				{
			 		org.omg.CORBA.Any any_tmp = org.omg.CORBA.ORB.init().create_any();
			 		any_tmp.insert_string(prf_mgr.m_Components.command_message.get(index).parameters.get(i).value.get(j));
					temp_prm[j] = new Parameter(
						prf_mgr.m_Components.command_message.get(index).parameters.get(i).name.get(j),
						prf_mgr.m_Components.command_message.get(index).parameters.get(i).datatype.get(j),
						any_tmp
					);
				}
				MessageProfile temp_msg = new MessageProfile(
					prf_mgr.m_Components.command_message.get(index).type.get(i),
					prf_mgr.m_Components.command_message.get(index).id.get(i),
					temp_prm
				);
				_profile.command_message[i] = temp_msg;
			}
			// query message
			msg_size = prf_mgr.m_Components.query_message.get(index).size;
			_profile.query_message = new MessageProfile[msg_size];
			for(int i=0; i<msg_size; i++)
			{
				prm_size = prf_mgr.m_Components.query_message.get(index).parameters.get(i).size;
				Parameter[] temp_prm = new Parameter[prm_size];
				for(int j=0; j<prm_size; j++)
				{
			 		org.omg.CORBA.Any any_tmp = org.omg.CORBA.ORB.init().create_any();
			 		any_tmp.insert_string(prf_mgr.m_Components.query_message.get(index).parameters.get(i).value.get(j));
					temp_prm[j] = new Parameter(
						prf_mgr.m_Components.query_message.get(index).parameters.get(i).name.get(j),
						prf_mgr.m_Components.query_message.get(index).parameters.get(i).datatype.get(j),
						any_tmp
					);
				}
				MessageProfile temp_msg = new MessageProfile(
					prf_mgr.m_Components.query_message.get(index).type.get(i),
					prf_mgr.m_Components.query_message.get(index).id.get(i),
					temp_prm
				);
				_profile.query_message[i] = temp_msg;
			}
			// event message
			msg_size = prf_mgr.m_Components.event_message.get(index).size;
			_profile.event_message = new MessageProfile[msg_size];
			for(int i=0; i<msg_size; i++)
			{
				prm_size = prf_mgr.m_Components.event_message.get(index).parameters.get(i).size;
				Parameter[] temp_prm = new Parameter[prm_size];
				for(int j=0; j<prm_size; j++)
				{
			 		org.omg.CORBA.Any any_tmp = org.omg.CORBA.ORB.init().create_any();
			 		any_tmp.insert_string(prf_mgr.m_Components.event_message.get(index).parameters.get(i).value.get(j));
					temp_prm[j] = new Parameter(
						prf_mgr.m_Components.event_message.get(index).parameters.get(i).name.get(j),
						prf_mgr.m_Components.event_message.get(index).parameters.get(i).datatype.get(j),
						any_tmp
					);
				}
				MessageProfile temp_msg = new MessageProfile(
					prf_mgr.m_Components.event_message.get(index).type.get(i),
					prf_mgr.m_Components.event_message.get(index).id.get(i),
					temp_prm
				);
				_profile.event_message[i] = temp_msg;
			}
			// component parameter
			prm_size = prf_mgr.m_Components.parameter.get(index).size;
			Parameter[] temp_comp_prm = new Parameter[prm_size];
			for(int i=0; i<prm_size; i++)
			{
		 		org.omg.CORBA.Any any_tmp = org.omg.CORBA.ORB.init().create_any();
		 		any_tmp.insert_string(prf_mgr.m_Components.parameter.get(index).value.get(i));
		 		temp_comp_prm[i] = new Parameter(
					prf_mgr.m_Components.parameter.get(index).name.get(i),
					prf_mgr.m_Components.parameter.get(index).datatype.get(i),
					any_tmp
				);
			}
			_profile.parameter = temp_comp_prm;
			roRes = ReturnCode_t.RoIS_OK;
		}
		else
		{
			_profile.command_message =  new MessageProfile[0];
			_profile.query_message = new MessageProfile[0];
			_profile.event_message = new MessageProfile[0];
			_profile.parameter = new Parameter[0];
			roRes = ReturnCode_t.RoIS_BAD_PARAMETER;
		}
		profile.value = _profile;
		return roRes;
	}

	@Override
	public ReturnCode_t get_error_detail(
		String error_id,
		String condition,
		ResultListHolder results
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_ERROR;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [get_error_detail]\n"
			+">>>error_id:"+ error_id+"\n"
			+">>>condition:"+ condition
		);

		//@@@@@@@@@@@@@@@@@@@@@@@@@
		//@@ NEED CONDITION CHECK
		//@@@@@@@@@@@@@@@@@@@@@@@@@

		if(m_lib.getErrorDetail(error_id, results))
		{
			roRes = ReturnCode_t.RoIS_OK;
		}
		return roRes;
	}

	@Override
	public ReturnCode_t bind(
		String servername
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_ERROR;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [bind]\n"
			+">>>servername:"+ servername
		);

		// call component function
		roRes = m_comp.bind();
		if(roRes==ReturnCode_t.RoIS_OK)
		{
			// update internal information
			m_lib.saveEngineName(servername);
		}
		return roRes;
	}

	@Override
	public ReturnCode_t release(
		String servername
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_ERROR;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [release]\n"
			+">>>servername:"+ servername
		);

		// call component function
		roRes = m_comp.release();
		if(roRes==ReturnCode_t.RoIS_OK)
		{
			// update internal information
			m_lib.eraseEngineName(servername);
		}
		return roRes;
	}

	@Override
	public ReturnCode_t get_parameter(
			ParameterListHolder parameters
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [get_parameter]"
		);

		// call component function
		roRes = m_comp.get_parameter(parameters);
		return roRes;
	}

	@Override
	public ReturnCode_t set_parameter(
		String servername,
		Parameter[] parameters,
		org.omg.CORBA.StringHolder command_id
	){
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [set_parameter]\n"
			+">>>servername:"+ servername
		);

		// create command_id (update internal information)
		command_id.value = m_lib.createCommandMessageID(servername, "set_parameter");
		// call component function
		roRes = m_comp.set_parameter(parameters, command_id);
		return roRes;
	}

	@Override
	public ReturnCode_t execute(
		String servername,
		String command_type,
		Argument[] arguments,
		org.omg.CORBA.StringHolder command_id
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [execute]\n"
			+">>>servername:"+ servername+"\n"
			+">>>command_type:"+ command_type
		);

		// create command_id (update internal information)
		command_id.value = m_lib.createCommandMessageID(servername, command_type);
		// call component function
		roRes = m_comp.execute(command_type, arguments, command_id);
		return roRes;
	}

	@Override
	public ReturnCode_t get_command_result(
		String servername,
		String command_id,
		String condition,
		ResultListHolder results
	){
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [get_command_result]\n"
			+">>>servername:"+ servername+"\n"
			+">>>command_id:"+ command_id+"\n"
			+">>>condition:"+ condition
		);

		//@@@@@@@@@@@@@@@@@@@@@@@@@
		//@@ NEED CONDITION CHECK
		//@@@@@@@@@@@@@@@@@@@@@@@@@

		// refer internal information
		if(m_lib.getCommandResult(command_id, results))
		{
			roRes = ReturnCode_t.RoIS_OK;
		}
		return roRes;
	}

	@Override
	public ReturnCode_t query(
		String query_type,
		String condition,
		ResultListHolder results
	){
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [query]\n"
			+">>>query_type:"+ query_type+"\n"
			+">>>condition:"+ condition
		);

		//@@@@@@@@@@@@@@@@@@@@@@@@@
		//@@ NEED CONDITION CHECK
		//@@@@@@@@@@@@@@@@@@@@@@@@@

		// call component function
		roRes = m_comp.query(query_type, condition, results);
		return roRes;
	}

	@Override
	public ReturnCode_t subscribe(
		String servername,
		String event_type,
		String condition,
		org.omg.CORBA.StringHolder subscribe_id
	){
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [subscribe]\n"
			+">>>servername:"+ servername+"\n"
			+">>>event_type:"+ event_type+"\n"
			+">>>condition:"+ condition
		);

		//@@@@@@@@@@@@@@@@@@@@@@@@@
		//@@ NEED CONDITION CHECK
		//@@@@@@@@@@@@@@@@@@@@@@@@@

		// create subscribe_id (update internal information)
		subscribe_id.value = m_lib.createEventSubscribeID(servername, event_type);
		// call component function
		roRes = m_comp.subscribe(event_type, condition, subscribe_id);
		return roRes;
	}

	@Override
	public ReturnCode_t unsubscribe(
		String servername,
		String subscribe_id
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [unsubscribe]\n"
			+">>>servername:"+ servername+"\n"
			+">>>subscribe_id:"+ subscribe_id
		);

		// erase subscribe_id (update internal information)
		m_lib.eraseEventSubscribeID(servername, subscribe_id);
		// call component function
		roRes = m_comp.unsubscribe(subscribe_id);
		return roRes;
	}

	@Override
	public ReturnCode_t get_event_detail(
		String servername,
		String event_id,
		String condition,
		ResultListHolder results
	)
	{
		ReturnCode_t roRes = ReturnCode_t.RoIS_OK;

		Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(
			"received [get_event_detail]\n"
			+">>>servername:"+ servername+"\n"
			+">>>event_id:"+ event_id+"\n"
			+">>>condition:"+ condition
		);

		//@@@@@@@@@@@@@@@@@@@@@@@@@
		//@@ NEED CONDITION CHECK
		//@@@@@@@@@@@@@@@@@@@@@@@@@

		// refer internal information
		if(m_lib.getEventDetail(event_id, results))
		{
			roRes = ReturnCode_t.RoIS_OK;
		}
		return roRes;
	}
}
